package com.lyc.api;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.codec.binary.Hex;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.net.URIBuilder;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: lyc
 * @Date: 2024/11/28 11:48
 */
public class SigmobApiClient {

    private static final Gson policyGson = new Gson();

    /**
     * 变现账户名
     */
    private static final String USER_NAME = "chenhaoran@zijjt.com";
    /**
     * Sigmob Secret Key，从平台账户管理->Keys功能页获取。<br/>
     * 注意，这里要使用Sigmob Secret Key，而不是ToBid Secret Key
     */
    private static final int APP_ID = 42498;

    private static final String SECRET_KEY = "60d127daa70cdc754d2b98fe1195619a";

    private static final String HEADER_NAME_SIGNATURE = "X-Open-Signature";

    private static final String HOST = "https://mmapi.sigmob.com";

    private static class SourceAuthContent {
        private String placementId;

        public String getPlacementId() {
            return placementId;
        }

        public void setPlacementId(String placementId) {
            this.placementId = placementId;
        }
    }

    public static void main(String[] args) throws IOException, URISyntaxException, NoSuchAlgorithmException {
        SourceAuthContent sac = new SourceAuthContent();
        sac.setPlacementId("4811548667321548");

        Map<String, Object> requestMap = new HashMap<String,Object>();
        requestMap.put("name", "测试广告源！11");
        requestMap.put("pub_code", "6396347412246422");
        requestMap.put("media_network_id", queryMediaAppId(16));
        requestMap.put("source_auth_content", sac);
        requestMap.put("price", 6666);

        // requestMap.put("source_auth_content", sac);
        // requestMap.put("app_id", 50455);
        // requestMap.put("page", "1,10");

        // 除了业务需要的请求参数外，需要追加时间戳_t参数以及_user参数用于签名验证
        // 服务端会校验时间戳参数 timestamp，请求时间在±5秒内有效
        // requestMap.put("_user", USER_NAME);
        // requestMap.put("_t", System.currentTimeMillis());

        //创建广告源
        String createGroupUrl = "https://mmapi.sigmob.com/srv/open/api/union_mediation/ad_source/create";
        try {
            System.out.println(doRequest(createGroupUrl, requestMap));
        } catch (NoSuchAlgorithmException | IOException | URISyntaxException e) {
            e.printStackTrace();
        }
    }

    /**
     * 新建广告位
     * @param name 广告位名称(长度限制30个字符)
     * @param adType 广告位类型，激励：1，开屏：2，插屏：4，原生：5，横幅：7
     * @return 返回广告位pub_code
     */
    public static String createPlacement(String name, Integer adType) throws IOException, URISyntaxException, NoSuchAlgorithmException {
        String url = HOST + "/srv/open/api/union_mediation/placement/create";

        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("name", name);
        requestMap.put("app_id", APP_ID);
        requestMap.put("ad_type", adType);

        String response = doRequest(url, requestMap);
        System.out.println("response = " + response);

        // 定义响应的类型
        Type responseType = new TypeToken<Map<String, Object>>() {}.getType();
        Map<String, Object> responseMap = policyGson.fromJson(response, responseType);

        // 获取 code
        int code = ((Number) responseMap.get("code")).intValue();

        if (code == 200) {
            // 获取 data
            Map<String, Object> data = (Map<String, Object>) responseMap.get("data");

            // 获取 pub_code
            String pubCode = (String) data.get("pub_code");
            // System.out.println("pub_code = " + pubCode);
            return pubCode;
        }

        return null;
    }

    /**
     * 查询ToBid Appid与广告网络账号的关联id
     * @param channelId 广告网络id
     * @return 返回ToBid Appid与广告网络账号的关联id
     */
    private static Integer queryMediaAppId(Integer channelId) throws IOException, URISyntaxException, NoSuchAlgorithmException {
        String url = HOST + "/srv/open/api/union_mediation/media_app/list";

        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("app_id", APP_ID);
        requestMap.put("channel_id", channelId);
        requestMap.put("page", "1,1");

        String response = doRequest(url, requestMap);
        System.out.println("response = " + response);

        // 定义响应的类型
        Type responseType = new TypeToken<Map<String, Object>>() {}.getType();
        Map<String, Object> responseMap = policyGson.fromJson(response, responseType);

        // 获取 code
        int code = ((Number) responseMap.get("code")).intValue();

        if (code == 200) {
            // 获取 data
            Map<String, Object> data = (Map<String, Object>) responseMap.get("data");

            // 获取 content 列表
            List<Map<String, Object>> contentList = (List<Map<String, Object>>) data.get("content");

            // 遍历 content 列表，提取 id
            for (Map<String, Object> content : contentList) {
                int id = ((Number) content.get("id")).intValue();
                // System.out.println("id = " + id);
                return id;
            }
        }

        return -1;
    }

    /**
     * 签名使用 SHA-1(160bit)算法生成<br/>
     *
     * @param plainText
     * @return
     * @throws NoSuchAlgorithmException
     */
    private static String sha1(String plainText) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA");
        byte[] cipherBytes = messageDigest.digest(plainText.getBytes());
        String cipherStr = Hex.encodeHexString(cipherBytes);
        return cipherStr;
    }

    public static String doRequest(String url, Map<String, Object> requestMap)
            throws IOException, URISyntaxException, NoSuchAlgorithmException {

        // 添加公共请求参数
        requestMap.put("_user", USER_NAME);
        requestMap.put("_t", System.currentTimeMillis());

        // 接口接收post方式的json数据，而不是form表单。所以需要把请求参数转换成json对象
        // ObjectMapper om = new ObjectMapper();
        // String json = om.writeValueAsString(requestMap);
        Type type = new TypeToken<Map<String, Object>>() {}.getType();
        String json = policyGson.toJson(requestMap, type);

        // 计算签名.签名由body加Sigmob Secret Key组成
        String plainTxt = json+SECRET_KEY;
        String signStr = sha1(plainTxt);

        URI uri = new URIBuilder(new URI(url)).build();

        StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);

        ClassicHttpRequest httpPost = ClassicRequestBuilder.post().setUri(uri).build();
        httpPost.setEntity(stringEntity);

        // 这里只能是 application/json，请勿添加其他信息，例如：application/json;charset=UTF-8
        httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
        // 增加签名http header
        httpPost.setHeader(HEADER_NAME_SIGNATURE, signStr);
        CloseableHttpClient httpclient = HttpClients.createDefault();

        return httpclient.execute(httpPost, response -> {
            System.out.println(response.getCode() + " " + response.getReasonPhrase());
            return EntityUtils.toString(response.getEntity());
        });
    }
}
